package com.resou.reader.data.tinder;

import android.util.Log;

import com.resou.reader.api.entry.Result;
import com.resou.reader.api.entry.ResultList;
import com.resou.reader.data.tinder.local.TinderLocalDataSource;
import com.resou.reader.data.tinder.remote.TinderRemoteDataSource;
import com.resou.reader.data.tinder.remote.TinderService;
import com.resou.reader.data.tinder.tinder.CartBook;
import com.resou.reader.data.tinder.tinder.SlideBean;
import com.resou.reader.utils.ToastUtil;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class TinderRepository {

    private static TinderRepository sInstance;

    private final TinderLocalDataSource mLocalDataSource;
    private final TinderRemoteDataSource mRemoteDataSource;
    private final TinderService mService;

    /**
     * 一个类应该从外部获取它的依赖
     *
     * @param localDataSource  本地数据源
     * @param remoteDataSource 远程数据源
     */
    private TinderRepository(TinderLocalDataSource localDataSource, TinderRemoteDataSource remoteDataSource) {
        mLocalDataSource = localDataSource;
        mRemoteDataSource = remoteDataSource;
        mService = mRemoteDataSource.getService();
    }

    public static TinderRepository getInstance(TinderLocalDataSource localDataSource, TinderRemoteDataSource remoteDataSource) {
        if (sInstance == null) {
            sInstance = new TinderRepository(localDataSource, remoteDataSource);
        }
        return sInstance;
    }

    public Observable<ResultList<SlideBean>> getSlideList(int page, String token, String deviceType) {
        return mRemoteDataSource.getSlideList(page, token, deviceType);
    }

    private static final String TAG = "TinderRepository-App";

    /**
     * 添加到收藏夹
     *
     * @param slideBean 要保存得对象
     * @param token     用户token
     * @return 添加到服务器得RxJava的Disposable
     */
    public Observable<Result> addToShoppingCart(final SlideBean slideBean, String token) {
        //添加到本地
        mLocalDataSource.saveToLocalSlideBean(slideBean);

        //添加到服务器
        return mRemoteDataSource.addToShoppingCart(slideBean.getBookId(), token)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.newThread())
                .doOnNext(new Consumer<Result>() {
                    @Override
                    public void accept(Result result) throws Exception {
                        if (result.getCode() == 0) {
                            //成功保存到服务器
                            Log.i(TAG, slideBean.getNovelName() + "-保存成功 ");
                        } else {
                            //todo 加入待同步列表
                            ToastUtil.makeLongToast(result.getMsg());
                        }
                    }
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        //上传服务器失败，加入待提交列表
                        mLocalDataSource.addToPendingSubmission(slideBean);
                    }
                });
    }

//    /**
//     * 加载收藏夹列表
//     *  @param slideBeanDao
//     * @param token
//     */
//    public Observable<ResultList<CartBook>> loadShoppingCart(SlideBeanDao slideBeanDao, final String token) {
//        final List<SlideBean> localSlideBeans = mLocalDataSource.loadLocalSlideBeans(slideBeanDao);
////        return mRemoteDataSource.getCartBookListAll(token)
////                .subscribeOn(Schedulers.io())
////                .observeOn(Schedulers.io())
////                .subscribe(new Consumer<ResultList<CartBook>>() {
////                    @Override
////                    public void accept(ResultList<CartBook> resultList) throws Exception {
////                        List<CartBook> books = resultList.getData();
////                        //比对服务器与本地的收藏夹同步与否，不同步则上传继续显示进度条
////                        for (int i = 0; i < localSlideBeans.size(); i++) {
////                            for (int j = 0; j < books.size(); j++) {
////                                SlideBean slideBean = localSlideBeans.get(i);
////                                if (!slideBean.equals(books.get(j))) {
////                                    mRemoteDataSource.addToShoppingCart(slideBean.getBookId(), token);
////                                }
////                            }
////                        }
////                    }
////                }, new Consumer<Throwable>() {
////                    @Override
////                    public void accept(Throwable throwable) throws Exception {
////
////                    }
////                })
////                ;
//    }

    public Observable<Result<String>> getCartCount(String token) {
        return mRemoteDataSource.getCartCount(token);
    }

    public Observable<ResultList<CartBook>> getCartBookListAll(String token) {
        return mRemoteDataSource.getCartBookListAll(token);
    }

    public Observable<Result<String>> delete(String token, final String bookId) {
        //删除已勾选的bookId
        return mService.delete(token, bookId)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.newThread())
                .doOnNext(new Consumer<Result<String>>() {
                    @Override
                    public void accept(Result<String> result) throws Exception {
                        if (result.getCode() == 0) {
                            Log.d(TAG, "accept:result " + result.getMsg());
                            //表示服务器删除成功，那么本地也删除
                            mLocalDataSource.deleteLocalCache(bookId);
                        }
                    }
                })
                .doOnError(new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        ToastUtil.makeLongToast(throwable.getMessage());
                    }
                });
    }

    public List<SlideBean> loadLocalCartCount() {
        return mLocalDataSource.loadLocalSlideBeans();
    }

    public Observable<List<SlideBean>> loadPendingSubmitSlideBean() {
        return Observable.create(new ObservableOnSubscribe<List<SlideBean>>() {
            @Override
            public void subscribe(ObservableEmitter<List<SlideBean>> emitter) throws Exception {
                List<SlideBean> slideBeans = mLocalDataSource.loadPendingSubmitSlideBean();
                if (slideBeans != null) {
                    emitter.onNext(slideBeans);
                }
            }
        });
    }
}
